OPC Studio User's Guide and Reference
Examples - OPC UA Alarms&Conditions - Acknowledge an event

.NET

// This example shows how to acknowledge an OPC UA event.
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .

using System;
using System.Threading;
using OpcLabs.EasyOpc.UA;
using OpcLabs.EasyOpc.UA.AddressSpace;
using OpcLabs.EasyOpc.UA.AddressSpace.Standard;
using OpcLabs.EasyOpc.UA.AlarmsAndConditions;
using OpcLabs.EasyOpc.UA.Filtering;
using OpcLabs.EasyOpc.UA.OperationModel;

namespace UADocExamples.AlarmsAndConditions
{
    partial class Acknowledge
    {
        public static void Main1()
        {
            // Define which server we will work with.
            UAEndpointDescriptor endpointDescriptor =
                "opc.tcp://opcua.demo-this.com:62544/Quickstarts/AlarmConditionServer";

            // Instantiate the client objects.
            var client = new EasyUAClient();
            IEasyUAAlarmsAndConditionsClient alarmsAndConditionsClient = client.AsAlarmsAndConditionsClient();

            UANodeId nodeId = null;
            byte[] eventId = null;
            var anEvent = new ManualResetEvent(initialState: false);

            Console.WriteLine("Subscribing...");
            client.SubscribeEvent(
                endpointDescriptor,
                UAObjectIds.Server,
                1000,
                new UAEventFilterBuilder(
                    UAFilterElements.Equals(
                        UABaseEventObject.Operands.NodeId,
                        new UANodeId(nodeIdExpandedText: "nsu=http://opcfoundation.org/Quickstarts/AlarmCondition ;ns=2;s=1:Colours/EastTank?Yellow")),
                    UABaseEventObject.AllFields),
                (sender, eventArgs) =>
                {
                    if (!eventArgs.Succeeded)
                    {
                        Console.WriteLine($"*** Failure: {eventArgs.ErrorMessageBrief}");
                        return;
                    }
                    if (!(eventArgs.EventData is null))
                    {
                        UABaseEventObject baseEventObject = eventArgs.EventData.BaseEvent;
                        Console.WriteLine(baseEventObject);

                        // Make sure we do not catch the event more than once.
                        if (anEvent.WaitOne(0))
                            return;

                        nodeId = baseEventObject.NodeId;
                        eventId = baseEventObject.EventId;

                        anEvent.Set();
                    }
                },
                state:null);

            Console.WriteLine("Waiting for an event for 30 seconds...");
            if (!anEvent.WaitOne(30*1000))
            {
                Console.WriteLine("Event not received.");
                return;
            }

            Console.WriteLine("Acknowledging an event...");
            try
            {
                alarmsAndConditionsClient.Acknowledge(
                    endpointDescriptor,
                    nodeId,
                    eventId,
                    "Acknowledged by an automated example code.");
            }
            catch (UAException uaException)
            {
                Console.WriteLine($"*** Failure: {uaException.GetBaseException().Message}");
            }

            Console.WriteLine("Waiting for 5 seconds...");
            Thread.Sleep(5 * 1000);

            Console.WriteLine("Unsubscribing...");
            client.UnsubscribeAllMonitoredItems();

            Console.WriteLine("Waiting for 5 seconds...");
            Thread.Sleep(5 * 1000);

            Console.WriteLine("Finished.");
        }



        // Example output:
        //Subscribing...
        //Waiting for an event for 30 seconds...
        //[EastTank] 100! "The alarm was acknoweledged." @11/9/2019 9:56:23 AM
        //Acknowledging an event...
        //Waiting for 5 seconds...
        //[EastTank] 100! "The alarm was acknoweledged." @11/9/2019 9:56:23 AM
        //Unsubscribing...
        //Waiting for 5 seconds...
        //Finished.
    }
}
# This example shows how to acknowledge an OPC UA event.
#
# Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .

#requires -Version 5.1
using namespace System.Threading
using namespace OpcLabs.EasyOpc.UA
using namespace OpcLabs.EasyOpc.UA.AddressSpace
using namespace OpcLabs.EasyOpc.UA.AddressSpace.Standard
using namespace OpcLabs.EasyOpc.UA.AlarmsAndConditions
using namespace OpcLabs.EasyOpc.UA.Filtering
using namespace OpcLabs.EasyOpc.UA.OperationModel

# The path below assumes that the current directory is [ProductDir]/Examples-NET/PowerShell/Windows .
Add-Type -Path "../../../Components/Opclabs.QuickOpc/net472/OpcLabs.EasyOpcUA.dll"
Add-Type -Path "../../../Components/Opclabs.QuickOpc/net472/OpcLabs.EasyOpcUAComponents.dll"

# Define which server we will work with.
[UAEndpointDescriptor]$endpointDescriptor = "opc.tcp://opcua.demo-this.com:62544/Quickstarts/AlarmConditionServer"

# Instantiate the client objects.
$client = New-Object EasyUAClient
$alarmsAndConditionsClient = $client.AsAlarmsAndConditionsClient()

# Event notification handler
Register-ObjectEvent -InputObject $client -EventName EventNotification -Action { 
    if (-not $EventArgs.Succeeded) {
        Write-Host "*** Failure: $($EventArgs.ErrorMessageBrief)"
        return
    }
    if ($EventArgs.EventData -ne $null) {
        $baseEventObject = $EventArgs.EventData.BaseEvent
        Write-Host $baseEventObject

        # Make sure we do not catch the event more than once.
        if ($acknowledged) {
            return
        }

        $global:nodeId = $baseEventObject.NodeId
        $global:eventId = $baseEventObject.EventId

        $global:acknowledged = $true
    }
}

Write-Host "Subscribing..."
$global:acknowledged = $false
[IEasyUAClientExtension]::SubscribeEvent($client, 
    $endpointDescriptor, 
    [UAObjectIds]::Server, 
    1000,
    [UAEventFilter](New-Object UAEventFilterBuilder(
        [UAFilterElements]::Equals(
            [UABaseEventObject+Operands]::NodeId, 
            (New-Object UANodeId("nsu=http://opcfoundation.org/Quickstarts/AlarmCondition ;ns=2;s=1:Colours/EastTank?Yellow"))),
        [UABaseEventObject]::AllFields))
    )

Write-Host "Waiting for an event for 30 seconds..."
$stopwatch =  [System.Diagnostics.Stopwatch]::StartNew() 
while ($stopwatch.Elapsed.TotalSeconds -lt 30) {    
    if ($global:acknowledged) {
        break
    }
    Start-Sleep -Seconds 1
}
if (-not $global:acknowledged) {
    Write-Host "Event not received."
    return
}

Write-Host "Acknowledging an event..."
try {
    $alarmsAndConditionsClient.Acknowledge(
        $endpointDescriptor,
        $global:nodeId,
        $global:eventId,
        "Acknowledged by an automated example code.")
}
catch [UAException] {
    Write-Host "*** Failure: $($PSItem.Exception.GetBaseException().Message)"
    return
}

Write-Host "Waiting for 5 seconds..."
Start-Sleep -Seconds 5

Write-Host "Unsubscribing..."
$client.UnsubscribeAllMonitoredItems()

Write-Host "Waiting for 5 seconds..."
Start-Sleep -Seconds 5

Write-Host "Finished."


# Example output:
#Subscribing...
#Waiting for an event for 30 seconds...
#[EastTank] 100! "The alarm was acknoweledged." @11/9/2019 9:56:23 AM
#Acknowledging an event...
#Waiting for 5 seconds...
#[EastTank] 100! "The alarm was acknoweledged." @11/9/2019 9:56:23 AM
#Unsubscribing...
#Waiting for 5 seconds...
#Finished.

#  This example shows how to acknowledge an OPC UA event.
#
# Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
# OPC client and subscriber examples in Python on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-Python .
# The QuickOPC package is needed. Install it using "pip install opclabs_quickopc".
import opclabs_quickopc
import time

# Import .NET namespaces.
from System.Collections.Generic import *
from OpcLabs.EasyOpc.UA import *
from OpcLabs.EasyOpc.UA.AddressSpace import *
from OpcLabs.EasyOpc.UA.Navigation import *
from OpcLabs.EasyOpc.UA.OperationModel import *


# Define which server we will work with.
endpointDescriptor = UAEndpointDescriptor('opc.tcp://opcua.demo-this.com:62544/Quickstarts/AlarmConditionServer')

# Define which alarm we will work with.
alarmNodeDescriptor = UANodeDescriptor(UANodeId(
    'http://opcfoundation.org/Quickstarts/AlarmCondition',  # namespaceUriString
    '1:Colours/EastTank?Yellow'))   # identifier

# Knowing the alarm node, and the fact that is an instance of NonExclusiveLevelAlarmType (or its subtype),
# determine what is its LowState/Id node.
lowStateIdBrowsePathElements = List[UABrowsePathElement]()
lowStateIdBrowsePathElements.Add(UABrowsePathElement.CreateSimple(UAQualifiedName('ns=0;s=LowState')))
lowStateIdBrowsePathElements.Add(UABrowsePathElement.CreateSimple(UAQualifiedName('ns=0;s=Id')))
lowStateIdNodeDescriptor = UANodeDescriptor(UABrowsePath(alarmNodeDescriptor, lowStateIdBrowsePathElements))

# Instantiate the client objects
client = EasyUAClient()

print('Reading the alarm state...')
try:
    lowStateId = IEasyUAClientExtension.ReadValue(client, endpointDescriptor, lowStateIdNodeDescriptor)
except UAException as uaException:
    print('*** Failure: ' + uaException.GetBaseException().Message)
    exit()

print('Id of LowState: ', lowStateId, sep='')

print()
print('Finished.')
' This example shows how to obtain acknowledge an event.
'
' Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .

Imports System
Imports System.Threading
Imports OpcLabs.EasyOpc.UA
Imports OpcLabs.EasyOpc.UA.AddressSpace
Imports OpcLabs.EasyOpc.UA.AddressSpace.Standard
Imports OpcLabs.EasyOpc.UA.AlarmsAndConditions
Imports OpcLabs.EasyOpc.UA.Filtering
Imports OpcLabs.EasyOpc.UA.OperationModel

Namespace AlarmsAndConditions
    Friend Class Acknowledge
        Public Shared Sub Main1()

            ' Instantiate the client object
            Dim client = New EasyUAClient()
            Dim alarmsAndConditionsClient As IEasyUAAlarmsAndConditionsClient = client.AsAlarmsAndConditionsClient()

            Dim nodeId As UANodeId = Nothing
            Dim eventId As Byte() = Nothing
            Dim anEvent = New ManualResetEvent(initialState:=False)

            Console.WriteLine("Subscribing...")
            client.SubscribeEvent(
                "opc.tcp://opcua.demo-this.com:62544/Quickstarts/AlarmConditionServer",
                UAObjectIds.Server,
                1000,
                New UAEventFilterBuilder(
                    UAFilterElements.Equals(
                        UABaseEventObject.Operands.NodeId,
                        New UANodeId(nodeIdExpandedText:="nsu=http://opcfoundation.org/Quickstarts/AlarmCondition ;ns=2;s=1:Colours/EastTank?Yellow")),
                        UABaseEventObject.AllFields),
                Sub(sender, eventArgs)
                    If Not eventArgs.Succeeded Then
                        Console.WriteLine("*** Failure: {0}", eventArgs.ErrorMessageBrief)
                        Return
                    End If
                    If eventArgs.EventData IsNot Nothing Then
                        Dim baseEventObject = eventArgs.EventData.BaseEvent
                        Console.WriteLine(baseEventObject)

                        ' Make sure we do not catch the event more than once
                        If anEvent.WaitOne(0) Then
                            Return
                        End If

                        nodeId = baseEventObject.NodeId
                        eventId = baseEventObject.EventId

                        anEvent.Set()
                    End If
                End Sub,
                state:=Nothing)

            Console.WriteLine("Waiting for an event for 30 seconds...")
            If Not anEvent.WaitOne(30 * 1000) Then
                Console.WriteLine("Event not received")
                Return
            End If

            Console.WriteLine("Acknowledging an event...")
            Try
                alarmsAndConditionsClient.Acknowledge(
                    "opc.tcp://opcua.demo-this.com:62544/Quickstarts/AlarmConditionServer",
                    nodeId,
                    eventId,
                    "Acknowledged by an automated example code")
            Catch uaException As UAException
                Console.WriteLine("Failure: {0}", uaException.GetBaseException().Message)
            End Try

            Console.WriteLine("Waiting for 5 seconds...")
            Thread.Sleep(5 * 1000)

            Console.WriteLine("Unsubscribing...")
            client.UnsubscribeAllMonitoredItems()

            Console.WriteLine("Waiting for 5 seconds...")
            Thread.Sleep(5 * 1000)
        End Sub
    End Class
End Namespace

COM

// This example shows how to acknowledge an OPC UA event.
//
// Find all latest examples here : https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .

type
  THelperMethods11 = class
    class function ObjectTypeIds_BaseEventType: _UANodeId; static;
    class function UAFilterElements_SimpleAttribute(TypeId: _UANodeId; simpleRelativeBrowsePathString: string): _UASimpleAttributeOperand; static;
    class function UABaseEventObject_Operands_NodeId: _UASimpleAttributeOperand; static;
    class function UABaseEventObject_Operands_EventId: _UASimpleAttributeOperand; static;
    class function UABaseEventObject_Operands_EventType: _UASimpleAttributeOperand; static;
    class function UABaseEventObject_Operands_SourceNode: _UASimpleAttributeOperand; static;
    class function UABaseEventObject_Operands_SourceName: _UASimpleAttributeOperand; static;
    class function UABaseEventObject_Operands_Time: _UASimpleAttributeOperand; static;
    class function UABaseEventObject_Operands_ReceiveTime: _UASimpleAttributeOperand; static;
    class function UABaseEventObject_Operands_LocalTime: _UASimpleAttributeOperand; static;
    class function UABaseEventObject_Operands_Message: _UASimpleAttributeOperand; static;
    class function UABaseEventObject_Operands_Severity: _UASimpleAttributeOperand; static;
    class function UABaseEventObject_AllFields: _UAAttributeFieldCollection; static;
  end;

type
  TClientEventHandlers11 = class
    procedure Client_EventNotification(
      ASender: TObject;
      sender: OleVariant;
      const eventArgs: _EasyUAEventNotificationEventArgs);
    private
      FAnEvent: Boolean;
      FEventId: OleVariant;
      FNodeId: _UANodeId;
    published
      property AnEvent: Boolean read FAnEvent write FAnEvent;
      property EventId: OleVariant read FEventId;
      property NodeId: _UANodeId read FNodeId;
  end;

procedure TClientEventHandlers11.Client_EventNotification(
  ASender: TObject;
  sender: OleVariant;
  const eventArgs: _EasyUAEventNotificationEventArgs);
var
  BaseEventObject: _UABaseEventObject;
begin
  if not eventArgs.Succeeded then
  begin
    WriteLn(Format('*** Failure: %s', [eventArgs.ErrorMessageBrief]));
    Exit;
  end;

  if eventArgs.EventData <> nil then
  begin
    BaseEventObject := eventArgs.EventData.BaseEvent;
      WriteLn(BaseEventObject.ToString);

    // Make sure we do not catch the event more than once
    if FAnEvent then
      Exit;

    FNodeId := BaseEventObject.NodeId;
    TVarData(FEventId).VType := varArray or varVariant;
    TVarData(FEventId).VArray := PVarArray(BaseEventObject.EventId);
    FAnEvent := True;
  end;
end;

class procedure Acknowledge.Main;
var
  AlarmsAndConditionsClient: _EasyUAAlarmsAndConditionsClient;
  Arguments: OleVariant;
  Client: TEasyUAClient;
  ClientEventHandlers: TClientEventHandlers11;
  EndpointDescriptor: string;
  EndTime: Cardinal;
  EventFilter: _UAEventFilter;
  MonitoredItemArguments: _EasyUAMonitoredItemArguments;
  MonitoringParameters: _UAMonitoringParameters;
  Operand1: _UASimpleAttributeOperand;
  Operand2: _UALiteralOperand;
  NodeDescriptor: _UANodeDescriptor;
  NodeId: _UANodeId;
  ServerNodeId: _UANodeID;
  WhereClause: _UAContentFilterElement;
begin
  // Define which server we will work with.
  EndpointDescriptor := 'opc.tcp://opcua.demo-this.com:62544/Quickstarts/AlarmConditionServer';

  // Event filter: Events with specific node ID.
  Operand1 := THelperMethods11.UABaseEventObject_Operands_NodeId;
  NodeId := CoUANodeId.Create;
  NodeId.ExpandedText := 'nsu=http://opcfoundation.org/Quickstarts/AlarmCondition ;ns=2;s=1:Colours/EastTank?Yellow';
  Operand2 := CoUALiteralOperand.Create;
  Operand2.Value := NodeId;
  WhereClause := CoUAContentFilterElement.Create;
  WhereClause.FilterOperator := UAFilterOperator_Equals;
  WhereClause.FilterOperands.Add(Operand1);
  WhereClause.FilterOperands.Add(Operand2);

  EventFilter := CoUAEventFilter.Create;
  EventFilter.SelectClauses := THelperMethods11.UABaseEventObject_AllFields;
  EventFilter.WhereClause := WhereClause;

  ServerNodeId := CoUANodeId.Create;
  ServerNodeId.StandardName := 'Server';

  MonitoringParameters := CoUAMonitoringParameters.Create;
  MonitoringParameters.EventFilter := EventFilter;
  MonitoringParameters.QueueSize := 1000;
  MonitoringParameters.SamplingInterval := 1000;

  MonitoredItemArguments := CoEasyUAMonitoredItemArguments.Create;
  MonitoredItemArguments.AttributeId := UAAttributeId_EventNotifier;
  MonitoredItemArguments.EndpointDescriptor.UrlString := EndpointDescriptor;
  MonitoredItemArguments.MonitoringParameters := MonitoringParameters;
  MonitoredItemArguments.NodeDescriptor.NodeId := ServerNodeId;

  // Instantiate the client object and hook events
  Client := TEasyUAClient.Create(nil);
  ClientEventHandlers := TClientEventHandlers11.Create;
  Client.OnEventNotification := ClientEventHandlers.Client_EventNotification;
  AlarmsAndConditionsClient := Client.AsAlarmsAndConditionsClient;
  ClientEventHandlers.AnEvent := False;

  Arguments := VarArrayCreate([0, 0], varVariant);
  Arguments[0] := MonitoredItemArguments;

  WriteLn('Subscribing...');
  Client.SubscribeMultipleMonitoredItems(Arguments);

  WriteLn('Waiting for an event for 30 seconds...');
  EndTime := Ticks + 30*1000;
  repeat
      if ClientEventHandlers.AnEvent or (EndTime < Ticks) then
        Break;
      PumpSleep(1000);
  until False;

  if ClientEventHandlers.AnEvent then
  begin
    WriteLn('Acknowledging an event...');
    try
      NodeDescriptor := CoUANodeDescriptor.Create;
      NodeDescriptor.NodeId := ClientEventHandlers.NodeId;
      AlarmsAndConditionsClient.Acknowledge(
       MonitoredItemArguments.EndpointDescriptor,
       NodeDescriptor,
       ClientEventHandlers.EventId,
       'Acknowledged by an automated example code.');
    except
      on E: EOleException do
      begin
        WriteLn(Format('*** Failure: %s', [E.GetBaseException.Message]));
        Exit;
      end;
    end;
  end
  else
  begin
    WriteLn('Event not received.');
  end;

  WriteLn('Waiting for 5 seconds...');
  PumpSleep(5*1000);

  WriteLn('Unsubscribing...');
  Client.UnsubscribeAllMonitoredItems;

  WriteLn('Waiting for 5 seconds...');
  Sleep(5*1000);

  WriteLn('Finished.');
  VarClear(Arguments);
  FreeAndNil(Client);
  FreeAndNil(ClientEventHandlers);
end;

// Example output:
// Subscribing...
// Waiting for an event for 30 seconds...
// [EastTank] 100! "The alarm was acknoweledged." @11/9/2019 9:56:23 AM
// Acknowledging an event...
// Waiting for 5 seconds...
// [EastTank] 100! "The alarm was acknoweledged." @11/9/2019 9:56:23 AM
// Unsubscribing...
// Waiting for 5 seconds...


class function THelperMethods11.ObjectTypeIds_BaseEventType: _UANodeId;
  var NodeId: _UANodeId;
  begin
    NodeId := CoUANodeId.Create;
    NodeId.StandardName := 'BaseEventType';
    Result := NodeId;
  end;

class function THelperMethods11.UAFilterElements_SimpleAttribute(TypeId: _UANodeId; simpleRelativeBrowsePathString: string): _UASimpleAttributeOperand;
var
  BrowsePathParser: _UABrowsePathParser;
  Operand: _UASimpleAttributeOperand;
begin
  BrowsePathParser := CoUABrowsePathParser.Create;
  Operand := CoUASimpleAttributeOperand.Create;
  Operand.TypeId.NodeId := TypeId;
  Operand.QualifiedNames := BrowsePathParser.ParseRelative(simpleRelativeBrowsePathString).ToUAQualifiedNameCollection;
  Result := Operand;
end;

class function THelperMethods11.UABaseEventObject_Operands_NodeId: _UASimpleAttributeOperand;
var
  Operand: _UASimpleAttributeOperand;
begin
  Operand := CoUASimpleAttributeOperand.Create;
  Operand.TypeId.NodeId.StandardName := 'BaseEventType';
  Operand.AttributeId := UAAttributeId_NodeId;
  Result := Operand;
end;

class function THelperMethods11.UABaseEventObject_Operands_EventId: _UASimpleAttributeOperand;
begin
  Result := UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, '/EventId');
end;

class function THelperMethods11.UABaseEventObject_Operands_EventType: _UASimpleAttributeOperand;
begin
  Result := UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, '/EventType');
end;

class function THelperMethods11.UABaseEventObject_Operands_SourceNode: _UASimpleAttributeOperand;
begin
  Result := UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, '/SourceNode');
end;

class function THelperMethods11.UABaseEventObject_Operands_SourceName: _UASimpleAttributeOperand;
begin
  Result := UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, '/SourceName');
end;

class function THelperMethods11.UABaseEventObject_Operands_Time: _UASimpleAttributeOperand;
begin
  Result := UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, '/Time');
end;

class function THelperMethods11.UABaseEventObject_Operands_ReceiveTime: _UASimpleAttributeOperand;
begin
  Result := UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, '/ReceiveTime');
end;

class function THelperMethods11.UABaseEventObject_Operands_LocalTime: _UASimpleAttributeOperand;
begin
  Result := UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, '/LocalTime');
end;

class function THelperMethods11.UABaseEventObject_Operands_Message: _UASimpleAttributeOperand;
begin
  Result := UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, '/Message');
end;

class function THelperMethods11.UABaseEventObject_Operands_Severity: _UASimpleAttributeOperand;
begin
  Result := UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, '/Severity');
end;

class function THelperMethods11.UABaseEventObject_AllFields: _UAAttributeFieldCollection;
var
  Fields: _UAAttributeFieldCollection;
begin
  Fields := CoUAAttributeFieldCollection.Create;
  Fields.Add(UABaseEventObject_Operands_NodeId.ToUAAttributeField);
  Fields.Add(UABaseEventObject_Operands_EventId.ToUAAttributeField);
  Fields.Add(UABaseEventObject_Operands_EventType.ToUAAttributeField);
  Fields.Add(UABaseEventObject_Operands_SourceNode.ToUAAttributeField);
  Fields.Add(UABaseEventObject_Operands_SourceName.ToUAAttributeField);
  Fields.Add(UABaseEventObject_Operands_Time.ToUAAttributeField);
  Fields.Add(UABaseEventObject_Operands_ReceiveTime.ToUAAttributeField);
  Fields.Add(UABaseEventObject_Operands_LocalTime.ToUAAttributeField);
  Fields.Add(UABaseEventObject_Operands_Message.ToUAAttributeField);
  Fields.Add(UABaseEventObject_Operands_Severity.ToUAAttributeField);

  Result := Fields;
end;
// This example shows how to acknowledge an OPC UA event.
//
// Find all latest examples here : https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .

const UAAttributeId_NodeId = 1;
const UAAttributeId_EventNotifier = 12;

const UAFilterOperator_Equals = 1;

class ClientEvents {
    private $AnEvent = false;
    private $EventId;
    private $NodeId;

    function EventNotification($Sender, $E)
    {
        if (!$E->Succeeded) {
            printf(" *** Failure: %s\n", $E->ErrorMessageBrief);
            return;
        }

        if (!is_null($E->EventData)) {
            $BaseEventObject = $E->EventData->BaseEvent;
            printf("%s\n", $BaseEventObject);

            // Make sure we do not catch the event more than once
           if ($this->AnEvent)
               return;

           $this->NodeId = $BaseEventObject->NodeId;
           $this->EventId = $BaseEventObject->EventId;
           $this->AnEvent = true;
        }
    }

    public function getAnEvent() {
        return $this->AnEvent;
    }

    public function getEventId() {
        return $this->EventId;
    }

    public function getNodeId() {
        return $this->NodeId;
    }
}


// Define which server we will work with.
$EndpointDescriptor = new COM("OpcLabs.EasyOpc.UA.UAEndpointDescriptor");
$EndpointDescriptor->UrlString = "opc.tcp://opcua.demo-this.com:62544/Quickstarts/AlarmConditionServer";

// Event filter: Events with specific node ID.
$Operand1 = UABaseEventObject_Operands_NodeId();
$NodeId = new COM("OpcLabs.EasyOpc.UA.AddressSpace.UANodeId");
$NodeId->ExpandedText = "nsu=http://opcfoundation.org/Quickstarts/AlarmCondition ;ns=2;s=1:Colours/EastTank?Yellow";
$Operand2 = new COM("OpcLabs.EasyOpc.UA.Filtering.UALiteralOperand");
$Operand2->Value = $NodeId;
$WhereClause = new COM("OpcLabs.EasyOpc.UA.Filtering.UAContentFilterElement");
$WhereClause->FilterOperator = UAFilterOperator_Equals;
$WhereClause->FilterOperands->Add($Operand1);
$WhereClause->FilterOperands->Add($Operand2);

$EventFilter = new COM("OpcLabs.EasyOpc.UA.UAEventFilter");
$EventFilter->SelectClauses = UABaseEventObject_AllFields();
$EventFilter->WhereClause = $WhereClause;

$ServerNodeId = new COM("OpcLabs.EasyOpc.UA.AddressSpace.UANodeId");
$ServerNodeId->StandardName = "Server";

$MonitoringParameters = new COM("OpcLabs.EasyOpc.UA.UAMonitoringParameters");
$MonitoringParameters->EventFilter = $EventFilter;
$MonitoringParameters->QueueSize = 1000;
$MonitoringParameters->SamplingInterval = 1000;

$MonitoredItemArguments = new COM("OpcLabs.EasyOpc.UA.OperationModel.EasyUAMonitoredItemArguments");
$MonitoredItemArguments->AttributeId = UAAttributeId_EventNotifier;
$MonitoredItemArguments->EndpointDescriptor = $EndpointDescriptor;
$MonitoredItemArguments->MonitoringParameters = $MonitoringParameters;
$MonitoredItemArguments->NodeDescriptor->NodeId = $ServerNodeId;

// Instantiate the client object and hook events
$Client = new COM("OpcLabs.EasyOpc.UA.EasyUAClient");
$ClientEvents = new ClientEvents();
com_event_sink($Client, $ClientEvents, "DEasyUAClientEvents");
$AlarmsAndConditionsClient = $Client->AsAlarmsAndConditionsClient;

$arguments[0] = $MonitoredItemArguments;

printf("Subscribing...\n");
$Client->SubscribeMultipleMonitoredItems($arguments);

printf("Waiting for an event for 30 seconds...\n");
$startTime = time(); do { com_message_pump(1000); } while ((time() < $startTime + 30) and !($ClientEvents->getAnEvent()));

if ($ClientEvents->getAnEvent()) {
    printf("Acknowledging an event...\n");
    try
    {
        $NodeDescriptor = new COM("OpcLabs.EasyOpc.UA.UANodeDescriptor");
        $NodeDescriptor->NodeId = $ClientEvents->getNodeId();
        $AlarmsAndConditionsClient->Acknowledge(
           $EndpointDescriptor,
           $NodeDescriptor,
           $ClientEvents->getEventId(),
           "Acknowledged by an automated example code.");
    }
    catch (com_exception $e)
    {
          printf("Failure: %s\n", $e->getMessage());
    }
}
else {
    printf("Event not received.\n");
}

printf("Waiting for 5 seconds...\n");
$startTime = time(); do { com_message_pump(1000); } while (time() < $startTime + 5);

printf("Unsubscribing...\n");
$Client->UnsubscribeAllMonitoredItems;

printf("Waiting for 5 seconds...\n");
$startTime = time(); do { com_message_pump(1000); } while (time() < $startTime + 5);


function ObjectTypeIds_BaseEventType() {
    $NodeId = new COM("OpcLabs.EasyOpc.UA.AddressSpace.UANodeId");
    $NodeId->StandardName = "BaseEventType";
    return $NodeId;
}

function UAFilterElements_SimpleAttribute($TypeId, $simpleRelativeBrowsePathString) {
  $BrowsePathParser = new COM("OpcLabs.EasyOpc.UA.Navigation.Parsing.UABrowsePathParser");
  $Operand = new COM("OpcLabs.EasyOpc.UA.Filtering.UASimpleAttributeOperand");
  $Operand->TypeId->NodeId = $TypeId;
  $Operand->QualifiedNames = $BrowsePathParser->ParseRelative($simpleRelativeBrowsePathString)->ToUAQualifiedNameCollection;
  return $Operand;
}

function UABaseEventObject_Operands_NodeId() {
    $Operand = new COM("OpcLabs.EasyOpc.UA.Filtering.UASimpleAttributeOperand");
    $Operand->TypeId->NodeId->StandardName = "BaseEventType";
    $Operand->AttributeId = UAAttributeId_NodeId;
    return $Operand;
}

function UABaseEventObject_Operands_EventId() {
  return UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType(), "/EventId");
}

function UABaseEventObject_Operands_EventType() {
  return UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType(), "/EventType");
}

function UABaseEventObject_Operands_SourceNode() {
  return UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType(), "/SourceNode");
}

function UABaseEventObject_Operands_SourceName() {
  return UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType(), "/SourceName");
}

function UABaseEventObject_Operands_Time() {
  return UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType(), "/Time");
}

function UABaseEventObject_Operands_ReceiveTime() {
  return UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType(), "/ReceiveTime");
}

function UABaseEventObject_Operands_LocalTime() {
  return UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType(), "/LocalTime");
}

function UABaseEventObject_Operands_Message() {
  return UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType(), "/Message");
}

function UABaseEventObject_Operands_Severity() {
  return UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType(), "/Severity");
}


function UABaseEventObject_AllFields() {
    $Fields = new COM("OpcLabs.EasyOpc.UA.UAAttributeFieldCollection");
    $Fields->Add(UABaseEventObject_Operands_NodeId()->ToUAAttributeField);
    $Fields->Add(UABaseEventObject_Operands_EventId()->ToUAAttributeField);
    $Fields->Add(UABaseEventObject_Operands_EventType()->ToUAAttributeField);
    $Fields->Add(UABaseEventObject_Operands_SourceNode()->ToUAAttributeField);
    $Fields->Add(UABaseEventObject_Operands_SourceName()->ToUAAttributeField);
    $Fields->Add(UABaseEventObject_Operands_Time()->ToUAAttributeField);
    $Fields->Add(UABaseEventObject_Operands_ReceiveTime()->ToUAAttributeField);
    $Fields->Add(UABaseEventObject_Operands_LocalTime()->ToUAAttributeField);
    $Fields->Add(UABaseEventObject_Operands_Message()->ToUAAttributeField);
    $Fields->Add(UABaseEventObject_Operands_Severity()->ToUAAttributeField);

    return $Fields;
}
Rem This example shows how to acknowledge an OPC UA event.
Rem
Rem Find all latest examples here : https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .

Option Explicit

Const UAAttributeId_NodeId = 1
Const UAAttributeId_EventNotifier = 12

Const UAFilterOperator_Equals = 1

' Define which server we will work with.
Dim EndpointDescriptor: Set EndpointDescriptor = CreateObject("OpcLabs.EasyOpc.UA.UAEndpointDescriptor")
EndpointDescriptor.UrlString = "opc.tcp://opcua.demo-this.com:62544/Quickstarts/AlarmConditionServer"

' Instantiate the client objects and hook events
Dim Client: Set Client = CreateObject("OpcLabs.EasyOpc.UA.EasyUAClient")
WScript.ConnectObject Client, "Client_"
Dim AlarmsAndConditionsClient: Set AlarmsAndConditionsClient = Client.AsAlarmsAndConditionsClient

'
Dim NodeId
Dim EventId
Dim anEvent: anEvent = False ' Some tools have event objects, but VBScript doesn't, we will use a boolean flag instead.

' Prepare arguments
Dim arguments(0)
Set arguments(0) = CreateMonitoredItemArguments

WScript.Echo "Subscribing..."
Client.SubscribeMultipleMonitoredItems arguments

WScript.Echo "Waiting for an event for 30 seconds..."
Dim endTime: endTime = Now() + 30*(1/24/60/60)
While (Not anEvent) And (Now() < endTime)
    WScript.Sleep 1000
WEnd
If Not anEvent Then
    WScript.Echo "Event not received."
    WScript.Quit
End If

WScript.Echo "Acknowledging an event..."
Dim NodeDescriptor: Set NodeDescriptor = CreateObject("OpcLabs.EasyOpc.UA.UANodeDescriptor")
Set NodeDescriptor.NodeId = NodeId
On Error Resume Next
AlarmsAndConditionsClient.Acknowledge EndpointDescriptor, NodeDescriptor, EventId, "Acknowledged by an automated example code."
If Err.Number <> 0 Then
    WScript.Echo "*** Failure: " & Err.Source & ": " & Err.Description
End If
On Error Goto 0

WScript.Echo "Waiting for 5 seconds..."
WScript.Sleep 5 * 1000

WScript.Echo "Unsubscribing..."
Client.UnsubscribeAllMonitoredItems

WScript.Echo "Waiting for 5 seconds..."
WScript.Sleep 5 * 1000



Function ObjectTypeIds_BaseEventType
    Dim NodeId: Set NodeId = CreateObject("OpcLabs.EasyOpc.UA.AddressSpace.UANodeId")
    NodeId.StandardName = "BaseEventType"
    Set ObjectTypeIds_BaseEventType = NodeId
End Function

Function UAFilterElements_SimpleAttribute(TypeId, simpleRelativeBrowsePathString)
    Dim BrowsePathParser: Set BrowsePathParser = CreateObject("OpcLabs.EasyOpc.UA.Navigation.Parsing.UABrowsePathParser")
    Dim Operand: Set Operand = CreateObject("OpcLabs.EasyOpc.UA.Filtering.UASimpleAttributeOperand")
    Set Operand.TypeId.NodeId = TypeId
    Set Operand.QualifiedNames = BrowsePathParser.ParseRelative(simpleRelativeBrowsePathString).ToUAQualifiedNameCollection
    Set UAFilterElements_SimpleAttribute = Operand
End Function

Function UABaseEventObject_Operands_NodeId
    Dim Operand: Set Operand = CreateObject("OpcLabs.EasyOpc.UA.Filtering.UASimpleAttributeOperand")
    Operand.TypeId.NodeId.StandardName = "BaseEventType"
    Operand.AttributeId = UAAttributeId_NodeId
    Set UABaseEventObject_Operands_NodeId = Operand
End Function

Function UABaseEventObject_Operands_EventId
    Set UABaseEventObject_Operands_EventId = UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, "/EventId")
End Function

Function UABaseEventObject_Operands_EventType
    Set UABaseEventObject_Operands_EventType = UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, "/EventType")
End Function

Function UABaseEventObject_Operands_SourceNode
    Set UABaseEventObject_Operands_SourceNode = UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, "/SourceNode")
End Function

Function UABaseEventObject_Operands_SourceName
    Set UABaseEventObject_Operands_SourceName = UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, "/SourceName")
End Function

Function UABaseEventObject_Operands_Time
    Set UABaseEventObject_Operands_Time = UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, "/Time")
End Function

Function UABaseEventObject_Operands_ReceiveTime
    Set UABaseEventObject_Operands_ReceiveTime = UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, "/ReceiveTime")
End Function

Function UABaseEventObject_Operands_LocalTime
    Set UABaseEventObject_Operands_LocalTime = UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, "/LocalTime")
End Function

Function UABaseEventObject_Operands_Message
    Set UABaseEventObject_Operands_Message = UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, "/Message")
End Function

Function UABaseEventObject_Operands_Severity
    Set UABaseEventObject_Operands_Severity = UAFilterElements_SimpleAttribute(ObjectTypeIds_BaseEventType, "/Severity")
End Function

Function UABaseEventObject_AllFields
    Dim Fields: Set Fields = CreateObject("OpcLabs.EasyOpc.UA.UAAttributeFieldCollection")

    Fields.Add UABaseEventObject_Operands_NodeId.ToUAAttributeField

    Fields.Add UABaseEventObject_Operands_EventId.ToUAAttributeField
    Fields.Add UABaseEventObject_Operands_EventType.ToUAAttributeField
    Fields.Add UABaseEventObject_Operands_SourceNode.ToUAAttributeField
    Fields.Add UABaseEventObject_Operands_SourceName.ToUAAttributeField
    Fields.Add UABaseEventObject_Operands_Time.ToUAAttributeField
    Fields.Add UABaseEventObject_Operands_ReceiveTime.ToUAAttributeField
    Fields.Add UABaseEventObject_Operands_LocalTime.ToUAAttributeField
    Fields.Add UABaseEventObject_Operands_Message.ToUAAttributeField
    Fields.Add UABaseEventObject_Operands_Severity.ToUAAttributeField

    Set UABaseEventObject_AllFields = Fields
End Function

Function CreateMonitoredItemArguments
    ' Event filter: Events with specific node ID.
    Dim Operand1: Set Operand1 = UABaseEventObject_Operands_NodeId
    Dim NodeId: Set NodeId = CreateObject("OpcLabs.EasyOpc.UA.AddressSpace.UANodeId")
    NodeId.ExpandedText = "nsu=http://opcfoundation.org/Quickstarts/AlarmCondition ;ns=2;s=1:Colours/EastTank?Yellow"
    Dim Operand2: Set Operand2 = CreateObject("OpcLabs.EasyOpc.UA.Filtering.UALiteralOperand")
    Set Operand2.Value = NodeId
    Dim WhereClause: Set WhereClause = CreateObject("OpcLabs.EasyOpc.UA.Filtering.UAContentFilterElement")
    WhereClause.FilterOperator = UAFilterOperator_Equals
    WhereClause.FilterOperands.Add Operand1
    WhereClause.FilterOperands.Add Operand2

    Dim EventFilter: Set EventFilter = CreateObject("OpcLabs.EasyOpc.UA.UAEventFilter")
    Set EventFilter.SelectClauses = UABaseEventObject_AllFields
    Set EventFilter.WhereClause = WhereClause

    Dim ServerNodeId: Set ServerNodeId = CreateObject("OpcLabs.EasyOpc.UA.AddressSpace.UANodeId")
    ServerNodeId.StandardName = "Server"

    Dim MonitoringParameters: Set MonitoringParameters = CreateObject("OpcLabs.EasyOpc.UA.UAMonitoringParameters")
    Set MonitoringParameters.EventFilter = EventFilter
    MonitoringParameters.QueueSize = 1000
    MonitoringParameters.SamplingInterval = 1000

    Dim MonitoredItemArguments: Set MonitoredItemArguments = CreateObject("OpcLabs.EasyOpc.UA.OperationModel.EasyUAMonitoredItemArguments")
    MonitoredItemArguments.AttributeId = UAAttributeId_EventNotifier
    MonitoredItemArguments.EndpointDescriptor = EndpointDescriptor
    Set MonitoredItemArguments.MonitoringParameters = MonitoringParameters
    Set MonitoredItemArguments.NodeDescriptor.NodeId = ServerNodeId

    Set CreateMonitoredItemArguments = MonitoredItemArguments
End Function

Sub Client_EventNotification(Sender, EventArgs)
    If Not EventArgs.Succeeded Then
        WScript.Echo "*** Failure: " & EventArgs.ErrorMessageBrief
        Exit Sub
    End If

    If Not (EventArgs.EventData Is Nothing) Then
        Dim BaseEventObject: Set BaseEventObject = EventArgs.EventData.BaseEvent
        WScript.Echo BaseEventObject

        ' Make sure we do not catch the event more than once
        If anEvent Then
            Exit Sub
        End If

        Set NodeId = BaseEventObject.NodeId
        EventId = BaseEventObject.EventId

        anEvent = True
    End If
End Sub



' Example output:
'Subscribing...
'Waiting for an event for 30 seconds...
'[EastTank] 100! "The alarm was acknoweledged." @11/9/2019 9:56:23 AM
'Acknowledging an event...
'Waiting for 5 seconds...
'[EastTank] 100! "The alarm was acknoweledged." @11/9/2019 9:56:23 AM
'Unsubscribing...
'Waiting for 5 seconds...

 

See Also

Conceptual

Examples - OPC Alarms&Events